package com.wzdigit.wms.raw.service.asn.report;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wzdigit.framework.Shift;
import com.wzdigit.wms.basic.client.response.basic.LocationApiResponse;
import com.wzdigit.wms.basic.domain.dtos.inventory.BindWarehousePositionDto;
import com.wzdigit.wms.basic.domain.dtos.inventory.UpdateInventoryInputDto;
import com.wzdigit.wms.basic.domain.inventory.Goods;
import com.wzdigit.wms.basic.domain.inventory.GoodsLog;
import com.wzdigit.wms.basic.domain.inventory.InvTrans;
import com.wzdigit.wms.basic.enums.GoodsStatusEnum;
import com.wzdigit.wms.basic.enums.InvTransStatusEnum;
import com.wzdigit.wms.basic.enums.OpCodeEnum;
import com.wzdigit.wms.basic.mapper.core.inventory.GoodsLogMapper;
import com.wzdigit.wms.basic.mapper.core.inventory.GoodsMapper;
import com.wzdigit.wms.basic.service.code.InventoryService;
import com.wzdigit.wms.raw.service.wmscommon.basic.LocationService;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.core.utils.BeanUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 上架绑定库位service
 * Created by zyf on 2021/7/19 18:15
 */
@Service
@Slf4j
public class BindLocService {
    @Autowired
    private GoodsMapper goodsMapper;
    @Autowired
    private GoodsLogMapper goodsLogMapper;

    @Autowired
    private LocationService locationService;
    @Autowired
    private InventoryService inventoryService;

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void bindWareHousePosition(BindWarehousePositionDto input, String userName) throws Exception{
        // 根据sn查数据
        QueryWrapper<Goods> queryWrapper = new QueryWrapper<Goods>();
        queryWrapper.in("GOODS_SN", input.goodsSns);
        List<Goods> wmsgoodList = goodsMapper.selectList(queryWrapper);

        // 判断是否全部SN状态都为“待上架”
        if (wmsgoodList.stream().filter(c -> !c.getStatus().equals(GoodsStatusEnum.WAIT_UP.getCode()))
                .count() > 0) {
            Shift.fatal("不允许上架！");
        }

        // 得出所有仓库id,个数大于1证明有不同的仓库
        if (wmsgoodList.stream().map(Goods::getWhsId).distinct().collect(Collectors.toList()).size() > 1) {
            Shift.fatal("当前这批SN存在不同仓库的数据");
        }

        // 仓库下的库位是否包含传进来的库位
        List<LocationApiResponse> locsEs = locationService.getLocationByWhs(wmsgoodList.get(0).getWhsId());
        if (locsEs.stream().filter(c -> c.getLocId().equals(input.getLocId())).count() == 0) {
            Shift.fatal("当前库位与SN所属仓库不一致");
        }

        Date date = new Date();
        String reason = "SN绑定库位";
        BigDecimal zero = BigDecimal.ZERO;
        String opCode = OpCodeEnum.PUTON.getCode();
        int goodsStatus = GoodsStatusEnum.HAS_UP.getCode();
        int invTransStatus = InvTransStatusEnum.FINISHED.getCode();


        // 根据传入的sn集合查询，根据仓库，货主，货品，工厂代码，供应商，批次号，库存性质，品质状态进行分组统计
        Map<String, List<Goods>> collect = wmsgoodList.stream().collect(Collectors.groupingBy(t ->
                (t.getWhsId() + "#" + t.getLocId() + "#" + t.getOwner() + "#" +
                        t.getSkuId() + "#" + t.getFactory() + "#" + t.getVendorId() + "#" +
                        t.getLotno() + "#" + t.getInvAttr() + "#" + t.getQaStatus() + "#"), Collectors.toList()));
        for (String key : collect.keySet()) {
            List<Goods> goodsCollect = collect.get(key);

            BigDecimal qty = goodsCollect.stream().map(t -> t.getQty()).reduce(zero, BigDecimal::add);

            UpdateInventoryInputDto toInv = new UpdateInventoryInputDto();
            toInv.setLocId(input.getLocId());
            toInv.setWhsId(goodsCollect.get(0).getWhsId());
            toInv.setOwner(goodsCollect.get(0).getOwner());
            toInv.setSkuId(goodsCollect.get(0).getSkuId());
            toInv.setFactory(goodsCollect.get(0).getFactory());
            toInv.setVendorId(goodsCollect.get(0).getVendorId());
            toInv.setLotNo(goodsCollect.get(0).getLotno());
            toInv.setInvAttr(goodsCollect.get(0).getInvAttr());
            toInv.setQaStatus(goodsCollect.get(0).getQaStatus());
            toInv.setUnit(goodsCollect.get(0).getUnit());
            toInv.setQty(qty);
            toInv.setPreInQty(zero);
            toInv.setPreOutQty(zero);
            toInv.setHoldQty(zero);
            toInv.setPreAlocQty(zero);
            toInv.setAlocQty(zero);
            toInv.setOperator(userName);

            UpdateInventoryInputDto fmInv = new UpdateInventoryInputDto();
            BeanUtil.copyNonNull(toInv, fmInv);
            fmInv.setQty(qty.negate());
            fmInv.setLocId(null);

            InvTrans invTrans = new InvTrans();
            invTrans.setOpCode(opCode);
            invTrans.setDocType(" ");
            invTrans.setDocNo(" ");
            invTrans.setDocLineNo(" ");
            invTrans.setTrsnNo(" ");
            invTrans.setTrsnLineNo(" ");
            invTrans.setStatus(invTransStatus);
            invTrans.setTransTime(date);
            invTrans.setOperator(userName);
            invTrans.setTransQty(qty);
            invTrans.setCreateTime(date);
            invTrans.setCreateUser(userName);
            Integer invtrsnId = inventoryService.inventoryTransfer(fmInv, toInv, invTrans);

            for (Goods goods : goodsCollect) {
                String goodsOriginalJson = JSON.toJSONString(goods);    // 原先的json

                goods.setModifyTime(date);
                goods.setModifyUser(userName);
                goods.setStatus(goodsStatus);
                goods.setLocId(input.getLocId());
                if (input.getDeletePkg() != null && input.getDeletePkg()) {
                    goods.setPkgId(null);
                }
                goodsMapper.updateLocIdAndPkgIdAndStatusById(goods);

                String goodsJson = JSON.toJSONString(goods);            // 更新后的json
                String jsonString = "未更新的:" + goodsOriginalJson + ",更新的:" + goodsJson;

                // 写入SN操作日志
                GoodsLog goodsLog = new GoodsLog();
                goodsLog.setInvTransId(invtrsnId);
                goodsLog.setGoodsSn(goods.getGoodsSn());
                goodsLog.setOpCode(opCode);
                goodsLog.setReason(reason);
                goodsLog.setUpdateContent(jsonString);
                goodsLog.setOperator(userName);
                goodsLog.setCreateUser(userName);
                goodsLog.setCreateTime(date);
                goodsLogMapper.insert(goodsLog);
            }
        }
    }
}
